#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctime>

using namespace std;

int main()
{
    // 1. 创建匿名管道
    int pipefd[2];
    int ret = pipe(pipefd);
    assert(ret == 0);
    (void)ret;

    // 2. 创建子进程
    pid_t id = fork();
    if (id == 0)
    {
        // 子进程内
        close(pipefd[1]); // 3. 子进程关闭写端

        // 4. 开始通信
        char buff[64];
        while (true)
        {
            int n = read(pipefd[0], buff, sizeof(buff) - 1);
            if (n <= 0)
            {
                cout << "子进程没有读取到信息，通信结束！" << endl;
                break;
            }

            buff[n] = '\0';

            if (n >= 5 && n < 64)
            {
                cout << "子进程成功读取到信息： " << buff << endl;
            }
            else
            {
                cout << "子进程读取数据量为：" << n << " 消息过短，通信结束！" << endl;
                break;
            }
        }

        close(pipefd[0]);
        exit(0);
    }
    else
    {
        // 父进程内
        close(pipefd[0]); // 3. 父进程关闭读端

        char buff[64];

        // 4. 开始通信
        srand((size_t)time(NULL));
        while (true)
        {
            int n = rand() % 26;
            for (int i = 0; i < n; i++)
                buff[i] = (rand() % 26) + 'A';
            buff[n] = '\0';

            cout << "=============================" << endl;
            cout << "父进程想对子进程说: " << buff << endl;
            write(pipefd[1], buff, strlen(buff));

            if (n < 5)
                break;

            sleep(1);
        }

        close(pipefd[1]);

        // 等待子进程退出
        int status = 0;
        waitpid(id, &status, 0);

        if (status & 0x7F)
        {
            printf("子进程异常退出,core dump: %d  退出信号：%d\n", (status >> 7) & 1, (status & 0x7F));
        }
        else
        {
            printf("子进程正常退出，退出码: %d\n", (status >> 8) & 0xFF);
        }

        return 0;
    }
}

